import math

# 构建跨度  梁,楼板


def calculate_distance(point1, point2):
    return math.sqrt(
        sum((a - b) ** 2 for a, b in zip(point1.Coordinates, point2.Coordinates))
    )


def calculate_beam(beam):
    for definition in beam.IsDefinedBy:
        if definition.is_a("IfcRelDefinesByProperties"):
            property_set = definition.RelatingPropertyDefinition
            # 检查是否是 'Pset_BeamCommon' 属性集
            if property_set.Name == "Pset_BeamCommon":
                for property in property_set.HasProperties:
                    # 查找名为 'Span' 的属性
                    if property.Name == "Span":
                        return property.NominalValue.wrappedValue

    return None

    # # 获取梁的几何表示
    # representation = beam.Representation
    # if representation:
    #     body = representation.Representations[0]  # 假设第一个表示是 'Body'
    #     items = body.Items
    #
    #     if items and len(items) > 0:
    #         geom = items[0]
    #
    #         if geom.is_a("IfcExtrudedAreaSolid"):
    #             depth = geom.Depth
    #             print(f"Beam {beam.id()} span: {depth}")
    #
    #         elif geom.is_a("IfcPolyline"):
    #             points = geom.Points
    #             if len(points) >= 2:
    #                 start = points[0]
    #                 end = points[-1]
    #                 span = calculate_distance(start, end)
    #                 print(f"Beam {beam.id()} span: {span}")
    #                 return span
    #
    #         # else:
    #         # print(f"Unsupported geometry type for Beam {beam.id()}: {geom.is_a()}")
    #     # else:
    #     #     print(f"No geometry items found for Beam {beam.id()}")
    # # else:
    # #     print(f"No representation found for Beam {beam.id()}")
    # return None


def calculate_slab(slab):
    representation = slab.Representation
    if not representation:
        return None

    # 假设第一个表示是 'Body'
    body = representation.Representations[0]
    items = body.Items

    if not items:
        return None

    geom = items[0]

    if geom.is_a("IfcExtrudedAreaSolid"):
        # 对于挤压体，我们需要检查其截面
        swept_area = geom.SweptArea
        if swept_area.is_a("IfcRectangleProfileDef"):
            # 对于矩形截面，我们可以直接获取长度和宽度
            length = swept_area.XDim
            width = swept_area.YDim
            return max(length, width)
        elif swept_area.is_a("IfcArbitraryClosedProfileDef"):
            # 对于任意闭合轮廓，我们需要计算其边界框
            outer_curve = swept_area.OuterCurve
            if outer_curve.is_a("IfcPolyline"):
                points = outer_curve.Points
                x_coords = [p.Coordinates[0] for p in points]
                y_coords = [p.Coordinates[1] for p in points]
                length = max(x_coords) - min(x_coords)
                width = max(y_coords) - min(y_coords)
                return max(length, width)

    elif geom.is_a("IfcFacetedBrep"):
        # 对于面片实体，我们需要计算其边界框
        verts = []
        for face in geom.Outer.CfsFaces:
            for loop in face.Bounds:
                for point in loop.Bound.Polygon:
                    verts.append(point.Coordinates)

        if verts:
            x_coords = [v[0] for v in verts]
            y_coords = [v[1] for v in verts]
            z_coords = [v[2] for v in verts]
            length = max(x_coords) - min(x_coords)
            width = max(y_coords) - min(y_coords)
            # height = max(z_coords) - min(z_coords)
            return max(length, width)
    return None


def calculate_span(product):
    if product.is_a("IfcBeam"):
        return calculate_beam(product)
    elif product.is_a("IfcSlab"):
        return calculate_slab(product)
